﻿using DLL.Net50.MotionCtrl.Vince.MC_Vsmd1x6Base;
using DLL.NET60.MotionCtrl.Entitys;
using DLL.NET70.Vince.DataFormat;
using DLL.Standard.Infrastructure.Log;
using Module.DialogService;
using Prism.Events;
using Prism.Services.Dialogs;
using System;
using System.Windows;

namespace DLL.Net.MotionCtrl.Vince.MSR4C_VsmdCtrl
{
    public interface IMC_MSTR4C_Vsmd : IMC_Vsmd1x6Base
    {
    }

    public class CMSR4C_VsmdCtrl : CMC_Vsmd1x6Base, IMC_MSTR4C_Vsmd
    {
        [Unity.Dependency]
        public IDialogService _dialogService { get; set; }

        public CMSR4C_VsmdCtrl(IEventAggregator eventAggregator, IDialogService dialogService, string deviceName = "MS4_ROBOT") : base(eventAggregator, dialogService, 0, deviceName)
        {
            this._dialogService = dialogService;
        }

        public override long GetLimitState(int AxisID, ref CLimit cl)
        {
            //LimitLowValid=1；没有感应到=1，感应到=0
            if (CardConnected == 0)
            {
                return 0;
            }
            long ret = 0;
            ret = ReadAxisStatus(AxisID, ref regbit);
            if (0 == ret)
            {
                return 0;
            }
            VC_MotorStadusBitReg nregbit = ConvertInput(regbit);
            CLimit al = new CLimit();
            al.NLimit = nregbit.B2_s3.Value;
            al.PLimit = nregbit.B3_s4.Value;
            al.HLimit = regbit.B7_AtHomePos.Value;
            cl = al;
            return 1;
        }

        public override long ReadInput()
        {
            if (CardConnected == 0)
            {
                return 0;
            }
            long ret = 0;
            int axisCount = GetAxisCountByInput();
            for (int AxisID = 0; AxisID < axisCount; AxisID++)
            {
                VC_MotorStadusBitReg regbit = new VC_MotorStadusBitReg();
                ret = ReadAxisStatus(AxisID, ref regbit);
                if (0 == ret)
                {
                    return 0;
                }
                VC_MotorStadusBitReg nregbit = ConvertInput(regbit);
                AllInput[CountIoOfOne * AxisID + 0] = nregbit.B0_s1.Value;
                AllInput[CountIoOfOne * AxisID + 1] = nregbit.B1_s2.Value;
            }
            return 1;
        }

        public override List<int> ReadOneAxisInput(int AxisID)
        {
            long ret = 0;
            List<int> input = new List<int>();
            VC_MotorStadusBitReg regbit = new VC_MotorStadusBitReg();
            ret = ReadAxisStatus(AxisID, ref regbit);
            if (0 == ret)
            {
                return null;
            }
            VC_MotorStadusBitReg nregbit = ConvertInput(regbit);

            input.Add(nregbit.B0_s1.Value);
            input.Add(nregbit.B1_s2.Value);
            return input;
        }

        private int WaitEmgOpen()
        {
            long ret = 0;
            bool emg = false;
            ret = GetEmgState(ref emg);
            if (0 == ret)
            {
                err = "获取急停按钮状态出现异常！";
                LogMessage(err, LogLevel.Warning);
                return 0;
            }
            while (!emg)
            {
                Application.Current.Dispatcher.Invoke(
                            (Action)delegate ()
                            {
                                _dialogService.ShowDialog(CommonDialogName.WarningDialog, new DialogParameters($"message={" 急停按钮被按下，无法继续配药，请打开急停按钮！"}"), null, CommonDialogName.CustomDialogWindow);
                            });

                ret = GetEmgState(ref emg);
                if (0 == ret)
                {
                    err = "获取急停按钮状态出现异常！";
                    LogMessage(err, LogLevel.Warning);
                    return 0;
                }
            }
            ExitType = 0;
            return 1;
        }

        public override int WetherQuitWaitStop(int AxisID)
        {
            bool emg = false;
            long ret = 0;
            ret = GetEmgState(ref emg);
            if (0 == ret)
            {
                err = AxisID.ToString() + "号轴：获取急停按钮状态出现异常！";
                LogMessage(err, LogLevel.Warning);
                return 0;
            }
            EmgState = emg;
            if ((EmgState == false) || (StopRun == 1))
            {
                Stop();
                if (EmgState == false)
                {
                    err = AxisID.ToString() + "号轴：急停按钮被按下！";
                    LogMessage(err, LogLevel.Warning);
                }
                if (StopRun == 1)
                {
                    err = AxisID.ToString() + "号轴：点击了停止按钮！";
                    LogMessage(err, LogLevel.Warning);
                    StopRun = 0;
                    return 0;
                }
                double[] OldDestPos = new double[10];
                //添加是退出，还是继续运行提示
                if ((1 == IsAutoRun))
                {
                    //在回完原点的情况下，才可以弹出对话框
                    ShowSelectedExceptionView();
                    int select = _excepetionType;
                    {
                        //在发现问题，尚未造成后果的情况下，按下的急停
                        ExitType = select;
                        if (select == 1)
                        {
                            //判断急停按钮是否已经打开
                            ret = WaitEmgOpen();
                            if (0 == ret)
                            {
                                return 0;
                            }
                            HomeOK = 1;
                            QuitAllMove = 0;
                            for (int i = 0; i < 10; i++)
                            {
                                OldDestPos[i] = AbsDestPos_mm[i];
                            }
                            if ((WorkPointID > 1) && (WorkPointID < 6))
                            {
                                if (AbsCurrentPos_mm[2] > OldDestPos[2])
                                {
                                    //Z轴向上运动，需要Z轴回抽，解决西林瓶内有有液体，拔针喷药
                                    for (int i = 2; i < motionParam.motionCardParam.UsedAxisCount; i++)
                                    {
                                        ret = AbsMove(i, 5, AbsCurrentPos_mm[i]);
                                        if (0 == ret)
                                        {
                                            return 0;
                                        }
                                    }
                                    ret = WaitForStop();
                                    if (0 == ret)
                                    {
                                        return 0;
                                    }
                                }
                            }
                            //下降Y轴
                            double yoldPos = AbsDestPos_mm[1];
                            ret = AbsMove(1, 0);
                            if (0 == ret)
                            {
                                return 0;
                            }
                            ret = WaitForStop(1);
                            if (0 == ret)
                            {
                                return 0;
                            }
                            bool ContinueWork = false;
                            Application.Current.Dispatcher.Invoke(
                            (Action)delegate ()
                            {
                                _dialogService.ShowDialog(CommonDialogName.AlertDialog, new DialogParameters($"message={" 是否继续配药？"}"), r =>
                                {
                                    if (r.Result == ButtonResult.Yes)
                                    {
                                        //执行回打溶媒动作
                                        ContinueWork = true;
                                    }
                                    else
                                    {
                                        ContinueWork = false;
                                    }
                                }, CommonDialogName.CustomDialogWindow);
                            });

                            if (true == ContinueWork)
                            {
                                //上升Y轴
                                AbsDestPos_mm[1] = yoldPos;
                                for (int i = 0; i < 2; i++)
                                {
                                    ret = AbsMove(i, AbsDestPos_mm[i]);
                                    if (0 == ret)
                                    {
                                        return 0;
                                    }
                                }
                                ret = WaitForStop(0);
                                ret = WaitForStop(1);
                                if (0 == ret)
                                {
                                    return 0;
                                }
                                //所有Z轴继续移动到目标位置
                                for (int i = 2; i < motionParam.motionCardParam.UsedAxisCount; i++)
                                {
                                    ret = AbsMove(i, OldDestPos[i]);
                                    if (0 == ret)
                                    {
                                        return 0;
                                    }
                                }
                                ret = WaitForStop();
                                if (0 == ret)
                                {
                                    return 0;
                                }
                            }
                            else
                            {
                                ExitType = 3;
                                QuitAllMove = 1;
                                err = AxisID.ToString() + "号轴：在急停按钮被按下的状态下，选择了退出运行！";
                                LogMessage(err, LogLevel.Warning);
                                return 0;
                            }
                        }
                        else if (select == 2)
                        {
                            //判断急停按钮是否已经打开
                            ret = WaitEmgOpen();
                            if (0 == ret)
                            {
                                return 0;
                            }
                            QuitAllMove = 0;
                            HomeOK = 1;
                            //有可能是，溶媒袋，或瓶子被顶出按下的急停。选择了退出当前动作
                            for (int i = 0; i < 10; i++)
                            {
                                OldDestPos[i] = AbsDestPos_mm[i];
                            }
                            if ((WorkPointID > 1) && (WorkPointID < 6))
                            {
                                //冲刷点位
                                //if (AbsCurrentPos_mm[2] > OldDestPos[2])
                                {
                                    //Z轴向上运动，需要Z轴回抽，解决西林瓶内有有液体，拔针喷药
                                    for (int i = 2; i < motionParam.motionCardParam.UsedAxisCount; i++)
                                    {
                                        ret = AbsMove(i, 5, 60);
                                        if (0 == ret)
                                        {
                                            return 0;
                                        }
                                    }
                                    ret = WaitForStop();
                                    if (0 == ret)
                                    {
                                        return 0;
                                    }
                                }
                            }

                            //Y轴移动到0点位置
                            ret = AbsMove(1, 0);
                            if (0 == ret)
                            {
                                return 0;
                            }
                            ret = WaitForStop(1);
                            if (0 == ret)
                            {
                                return 0;
                            }
                            err = AxisID.ToString() + "号轴：在急停按钮被按下的状态下，选择了退出当前动作！";
                            LogMessage(err, LogLevel.Warning);
                            ExitType = 2;
                            QuitAllMove = 0;
                            return 0;
                        }
                        else
                        {
                            //有可能是堵转原因拍下了急停，直接退出
                            ExitType = 3;
                            QuitAllMove = 1;
                            err = AxisID.ToString() + "号轴：在急停按钮被按下的状态下，选择了退出运行！";
                            LogMessage(err, LogLevel.Warning);
                            return 0;
                        }
                    }
                }
                else
                {
                    //没有启用操作提示
                    QuitAllMove = 1;
                    ExitType = 3;
                    return 0;
                }
            }
            else
            {
                ExitType = 0;
            }
            return 1;
        }

        public void ShowSelectedExceptionView()
        {
            string DialogName = CommonDialogName.YesCancelContinueDialog;
            CYesCancelContinueParam param = new CYesCancelContinueParam();
            param.Message = "在运动的过程中按下了急停按钮，根据当前设备运行状况，选择相应的处理方式";
            param.Yes = "继续配药";
            param.Continue = "退出当前动作";
            param.Cancel = "退出配药";
            IDialogParameters dialogParameters = new DialogParameters();
            dialogParameters.Add("CYesCancelContinueParam", new CYesCancelContinueParam());
            Application.Current.Dispatcher.Invoke(
                (Action)delegate ()
                {
                    _dialogService.ShowDialog(DialogName, dialogParameters, SelectedExceptionCallback, CommonDialogName.CustomDialogWindow);
                });
        }

        private int _excepetionType = 0;

        private void SelectedExceptionCallback(IDialogResult dialogResult)
        {
            if (dialogResult.Result == ButtonResult.OK)
            {
                int selected = dialogResult.Parameters.GetValue<int>("Selected");
                _excepetionType = selected;
            }
        }
    }
}